home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-11 | 14.3 KB | 541 lines | [TEXT/R*ch] |
- /*
-
- Listing 2: BackdropCanvas .java
-
- BackdropCanvas.java
- Define and create a new instance of our drawing canvas.
-
- */
-
- // Import the generic Java classes.
- import java.applet.*;
- import java.awt.*;
- import java.io.*;
- import java.lang.*;
-
- // Our class definition.
- // It is public so it can be used by classes not defined in this file.
- // It is named BackdropCanvas, and is descended from Canvas.
- public class BackdropCanvas extends Canvas
- {
-
- // Several property/variable declarations.
- // Since these are external to any of our methods within the class,
- // they can be considered global to those methods.
-
- // We need to keep track of our background color.
- Color theCanvasBackgroundColor = Color.gray;
-
- // References to objects we will create and draw.
- // Initialize to null just to be safe.
- DecafObject theCurrentDecafObject = null;
- DecafObject theNewDecafObject = null;
- DecafObject theFirstDecafObject = null;
-
- // Mouse state and location information.
- boolean mouseIsDown = false;
- boolean insideGrow = false;
- int xOffset = 0, yOffset = 0;
-
- // The current color selections for our canvas, panel, button, and text area
- // backgrounds and foregrounds.
- int theColorArray[] = new int[ 7 ];
-
- // Counters to track how many of each type we have created.
- static int thePanelID = 0, theButtonID = 0; static int theTextAreaID = 0;
-
- // Two sets of declarations used as constants.
- // One for the type of object we are creating,
- // the other for the alignment of any text drawn within that object.
- // They get passed to new objects during the creation process.
-
- // theObjectType: 0 = Panel, 1 = Button, 2 = Text Area
- static int thePanelType = 0, theButtonType = 1; static int theTextAreaType = 0;
-
- // theTextAlignment: 0 = Left, 1 = Center, 2 = Right
- static int theLeftAlignment = 0;
- static int theCenterAlignment = 0;
- static int theRightAlignment = 0;
-
-
- // Our class constructor, or what should happen when a new instance of
- // this class is created.
- public BackdropCanvas()
- {
- setBackground( theCanvasBackgroundColor );
- }
-
- // Change our canvas background color on demand.
- public void doSetBackgroundColor( Color theColor )
- {
- theCanvasBackgroundColor = theColor;
- setBackground( theCanvasBackgroundColor );
- }
-
- // Determine appropriate color when creating new objects.
- // Refer back to our declaration of theColorArray above.
- public int doFindColor( int itemNo )
- {
- return theColorArray[ itemNo ];
- }
-
- // Change colors for new and selected objects.
- public boolean doChangeColor( int theItem, int theColor )
- {
- boolean changedItem = false;
- int theObjectType = 0;
- DecafObject theTempDecafObject = theFirstDecafObject;
-
- while ( theTempDecafObject != null )
- {
- if ( theTempDecafObject.DoGetSelected() )
- {
- theObjectType =
- theTempDecafObject.DoGetObjectType();
- break;
- }
-
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
-
- theColorArray[ theItem ] = theColor;
-
- if ( theTempDecafObject != null )
- {
- switch ( theItem )
- {
- case 1:
- if ( theObjectType == 0 )
- {
- theTempDecafObject.doSetBackColor( theColor );
- changedItem = true;
- }
-
- break;
-
- case 2:
- if ( theObjectType == 0 )
- {
- theTempDecafObject.doSetTextColor( theColor );
- changedItem = true;
- }
-
- break;
-
- case 3:
- if ( theObjectType == 1 )
- {
- theTempDecafObject.doSetBackColor( theColor );
- changedItem = true;
- }
-
- break;
-
- case 4:
- if ( theObjectType == 1 )
- {
- theTempDecafObject.doSetTextColor( theColor );
- changedItem = true;
- }
-
- break;
-
- case 5:
- if ( theObjectType == 2 )
- {
- theTempDecafObject.doSetBackColor( theColor );
- changedItem = true;
- }
-
- break;
-
- case 6:
- if ( theObjectType == 2 )
- {
- theTempDecafObject.doSetTextColor( theColor );
- changedItem = true;
- }
-
- break;
-
- default:
- break;
- }
- }
-
- if ( changedItem )
- repaint();
-
- return changedItem;
- }
-
- // For deleting a selected object.
- public boolean doDeleteDecafObject()
- {
-
- // Long variable names here, which make the code difficult to read.
- // Replace with shorter names such as tempDC.
- boolean objectDeleted = false;
- DecafObject theTempDecafObject = null;
- DecafObject thePreviousTempDecafObject = null;
- DecafObject theNextTempDecafObject = null;
-
- // Walk through our list of objects, looking for the one that is selected.
- // This code or variations of it will be used in several places within this class.
- // It is a good candidate for a separate method.
-
- // In this case, start with the first object in the list.
- // If it is selected (e.g. the user clicked on it), remove its
- // references to the objects before and after it in the list.
- // Instead, set those objects to point at each other.
- // That is the purpose of the method DoDeleteDecafObject().
-
- // Note that special things happen if we are dealing with either:
- // a. the last object created (theCurrentDecafObject), or
- // b. the first object in the list (theFirstDecafObject).
-
- theTempDecafObject = theFirstDecafObject;
-
- while ( theTempDecafObject != null )
- {
- if ( theTempDecafObject.DoGetSelected() )
- {
- thePreviousTempDecafObject =
- theTempDecafObject.doGetPreviousDecafObject();
-
- theNextTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
-
- theTempDecafObject.DoDeleteDecafObject();
-
- if ( theCurrentDecafObject == theTempDecafObject )
- {
- if ( thePreviousTempDecafObject != null )
- theCurrentDecafObject =
- thePreviousTempDecafObject;
- else
- theCurrentDecafObject = null;
- }
-
- if ( theFirstDecafObject == theTempDecafObject )
- {
- if ( theNextTempDecafObject != null )
- theFirstDecafObject = theNextTempDecafObject;
- else
- theFirstDecafObject = null;
- }
-
- objectDeleted = true;
- break;
- }
-
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
-
- return( objectDeleted );
- }
-
- // For creating a new object.
- public boolean doAddDecafObject( int theType,
- String theString )
- {
- int theColor;
- DecafObject theTempDecafObject = theFirstDecafObject;
-
- // Use links between objects to find the last one created.
- while ( theTempDecafObject != null )
- {
- theTempDecafObject.DoSetSelected( false );
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
-
- theNewDecafObject = new DecafObject();
-
- // Setup the object references for our linked list.
- if ( theCurrentDecafObject != null )
- {
- theNewDecafObject.doSetPreviousDecafObject(
- theCurrentDecafObject );
-
- theCurrentDecafObject.doSetNextDecafObject(
- theNewDecafObject );
- }
-
- // Set various properties for our new object.
- // Much of this code can be carefully moved to the DecafObject class
- // as initialization code.
- theNewDecafObject.DoSetObjectType( theType );
-
- switch ( theType )
- {
- case 0:
- theColor = this.doFindColor( 1 );
- theNewDecafObject.doSetBackColor( theColor );
- theColor = this.doFindColor( 2 );
- theNewDecafObject.doSetTextColor( theColor );
- theNewDecafObject.DoSetTextAlignment(
- theLeftAlignment );
- thePanelID++;
- theNewDecafObject.DoSetID( thePanelID );
- break;
-
- case 1:
- theColor = this.doFindColor( 3 );
- theNewDecafObject.doSetBackColor( theColor );
- theColor = this.doFindColor( 4 );
- theNewDecafObject.doSetTextColor( theColor );
- theNewDecafObject.DoSetTextAlignment(
- theCenterAlignment );
- theButtonID++;
- theNewDecafObject.DoSetID( theButtonID );
- break;
-
- case 2:
- theColor = this.doFindColor( 5 );
- theNewDecafObject.doSetBackColor( theColor );
- theColor = this.doFindColor( 6 );
- theNewDecafObject.doSetTextColor( theColor );
- theNewDecafObject.DoSetTextAlignment(
- theLeftAlignment );
- theTextAreaID++;
- theNewDecafObject.DoSetID( theTextAreaID );
- break;
-
- default:
- break;
- }
-
- if ( theType == 0 )
- {
- String tempString = new String();
-
- theString = tempString.valueOf( thePanelID );
- }
-
- theNewDecafObject.DoSetText( theString );
- theNewDecafObject.DoSetupCanvasComponent();
- theNewDecafObject.DoSetSelected( true );
-
- if ( theFirstDecafObject == null )
- theFirstDecafObject = theNewDecafObject;
-
- theCurrentDecafObject = theNewDecafObject;
-
- return true;
- }
-
- // Override the Canvas paint event handler for painting all currently existing objects.
- public void paint( Graphics g )
- {
- int theHeight = 0, theWidth = 0;
- int theAscent = 0, theLeading = 0;
- int i = 0, theMaxHeight;
- int theXOffset = 1, theYOffset = 1;
- FontMetrics theFontMetrics;
- Rectangle theBounds = new Rectangle();
- DecafObject theTempDecafObject = theFirstDecafObject;
-
- // Get font information for this piece of canvas.
- // We need it for drawing text within our objects.
- theFontMetrics = g.getFontMetrics();
- theHeight = theFontMetrics.getHeight();
- theAscent = theFontMetrics.getAscent();
- theLeading = theFontMetrics.getLeading();
- theMaxHeight = theFontMetrics.getMaxAscent();
-
- // Another case where we walk through our linked list of objects.
- while ( theTempDecafObject != null )
- {
- theXOffset = 1;
- theYOffset = 1;
-
- theBounds = theTempDecafObject.DoGetBounds();
-
- // The bounding rectangle is used for determining if text fits within a button.
- // If not, adjust the bounds to center the text with a small buffer on each side.
- if ( theTempDecafObject.DoGetObjectType() ==
- theButtonType )
- {
- theWidth = theFontMetrics.stringWidth(
- theTempDecafObject.DoGetText() );
-
- if ( theBounds.width < theWidth + 2 )
- {
- theBounds.width = theWidth + 2;
- theTempDecafObject.DoSetBounds( theBounds );
- }
-
- theXOffset = ( theBounds.width - theWidth ) / 2;
- theYOffset = ( theBounds.height - theHeight ) / 2;
- }
-
- // Select the paint color and paint the object's outline.
- g.setColor( theTempDecafObject.doGetBackColor() );
-
- if ( theTempDecafObject.DoGetSelected() )
- g.fill3DRect( theBounds.x, theBounds.y,
- theBounds.width, theBounds.height, true );
- else
- g.drawRect( theBounds.x, theBounds.y,
- theBounds.width, theBounds.height );
-
- // Select the paint color and paint the object's text.
- g.setColor( theTempDecafObject.doGetTextColor() );
-
- switch ( theTempDecafObject.DoGetObjectType() )
- {
- case 0:
- g.drawString( theTempDecafObject.DoGetText(),
- theBounds.x + theXOffset, theBounds.y +
- theYOffset + theMaxHeight );
- break;
-
- case 1:
- g.drawString( theTempDecafObject.DoGetText(),
- theBounds.x + theXOffset, theBounds.y +
- theYOffset + theAscent + theLeading );
- break;
-
- case 2:
- g.drawString( theTempDecafObject.DoGetText(),
- theBounds.x + theXOffset, theBounds.y +
- theMaxHeight + theYOffset );
- break;
- }
-
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
- }
-
- // Override the Canvas mouseDown event handler.
- public boolean mouseDown( Event evt, int x, int y )
- {
- int i = 0;
- boolean doRepaint = false, foundItem = false;
- DecafObject theTempDecafObject = theFirstDecafObject;
- Rectangle theBounds = new Rectangle();
- boolean isInside = false;
-
- // Start with a clean slate (e.g. no objects selected).
- while ( theTempDecafObject != null )
- {
- theTempDecafObject.DoSetSelected( false );
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
-
- // Yet another walk through our object list.
- // Find the first object that contains the mouseDown location (x and y).
- // Check to see if the click is within our grow area for the object.
- // (The grow area size should be defined somewhere for easy modification.
- // It might be a property to make user-definable.)
- // Get the x and y offsets from the upper left corner of the object, so we can
- // redraw it in relation to where the mouseUp occurs.
- // Once we have found our object and set the appropriate values, exit the loop.
-
- theTempDecafObject = theFirstDecafObject;
-
- while ( theTempDecafObject != null )
- {
- theBounds = theTempDecafObject.DoGetBounds();
-
- if ( theBounds.inside( x, y ) )
- {
- if ( ( x < theBounds.x + theBounds.width ) &&
- ( x > theBounds.x + theBounds.width - 5 ) &&
- ( y < theBounds.y + theBounds.height ) &&
- ( y > theBounds.y + theBounds.height - 5 ) )
- theTempDecafObject.DoSetInsideGrow( true );
-
- xOffset = x - theBounds.x;
- yOffset = y - theBounds.y;
-
- theTempDecafObject.DoSetSelected( true );
- isInside = true;
- foundItem = true;
- }
-
- if ( foundItem )
- break;
-
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
-
- mouseIsDown = true;
- return true;
- }
-
- // Override the Canvas mouseUp event handler.
- public boolean mouseUp( Event evt, int x, int y )
- {
- boolean foundItem = false;
- DecafObject theTempDecafObject = theFirstDecafObject;
- Rectangle theBounds = new Rectangle();
-
- // If we matched the coords of the mouseDown event, and the user is releasing the
- // button within our canvas, we will handle the mouseUp.
- if ( mouseIsDown )
- {
- if ( this.inside( x, y ) )
- {
- while ( theTempDecafObject != null )
- {
- // Walk through the object list, looking for the selected object.
- // Either move or resize the selected object, depending on where the
- // mouseDown occured.
- if ( theTempDecafObject.DoGetSelected() )
- {
- theBounds = theTempDecafObject.DoGetBounds();
-
- if ( theTempDecafObject.DoGetInsideGrow() )
- theBounds.resize( theBounds.width + ( x -
- ( theBounds.x + theBounds.width ) ),
- theBounds.height + ( y - ( theBounds.y +
- theBounds.height ) ) );
- else
- theBounds.move( x - xOffset, y - yOffset );
-
- theTempDecafObject.DoSetBounds( theBounds );
- xOffset = 0;
- yOffset = 0;
- foundItem = true;
- }
-
- theTempDecafObject.DoSetInsideGrow( false );
-
- if ( foundItem )
- break;
-
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
- }
-
- // If we did not find a selected object matching the x and y coordinates,
- // deselect all objects.
- if ( !foundItem )
- {
- theTempDecafObject = theFirstDecafObject;
-
- while ( theTempDecafObject != null )
- {
- theTempDecafObject.DoSetSelected( false );
- theTempDecafObject =
- theTempDecafObject.doGetNextDecafObject();
- }
- }
-
- repaint();
- }
-
- mouseIsDown = false;
- return true;
- }
-
- }
-